local gui = require('gui')
local guidm = require('gui.dwarfmode')
local widgets = require('gui.widgets')
-- local automelt = reqscript("automelt")
local entity = df.global.plotinfo.main.fortress_entity
local defs = df.global.world.raws.itemdefs
local utils = require 'utils'
local json = require('json')

local tile_attrs = df.tiletype.attrs


--
-- vars
s_mat = { 
    copper=true, 
    iron=true, 
    bronze=true, 
    ["bismuth bronze"]=true,
    steel=false,
    silver=false,
    platinum=false,
    ["divine metal"]=false,
    adamantine=false
}
s_quality = {
    ["0"]= true,
    ["1"]= true,
    ["2"]= true,
    ["3"]= true,
    ["4"]= true,
    ["5"]= false,
    ["6"]= false,
}




local function get_priority_block_square_event(block_events)
    for i,v in ipairs(block_events) do
        if v:getType() == df.block_square_event_type.designation_priority then
            return v
        end
    end
    return nil
end
-- modifies any existing priority block_square_event to the specified priority.
-- if the block_square_event doesn't already exist, create it.
local function set_priority(digctx, priority)
    local block_events = dfhack.maps.getTileBlock(digctx.pos).block_events
    local pbse = get_priority_block_square_event(block_events)
    if not pbse then
        block_events:insert('#',
                            {new=df.block_square_event_designation_priorityst})
        pbse = block_events[#block_events-1]
    end
    pbse.priority[digctx.pos.x % 16][digctx.pos.y % 16] = priority * 1000
end

local function designateDig(pos)
    if (pos.x > 1 or pos.x < df.global.world.map.x_count) and (pos.y > 1 or pos.y < df.global.world.map.y_count) then
        local designation = dfhack.maps.getTileFlags(pos)
        local tile_type = dfhack.maps.getTileType(pos)
        if tile_attrs[tile_type].shape == df.tiletype_shape.WALL and designation.dig ~= df.tile_dig_designation.Default then
            designation.dig = df.tile_dig_designation.Default
            set_priority( {pos=pos} , 3)
            dfhack.maps.getTileBlock(pos).flags.designated = true
        end
    end
end
local function designateStair(pos)
    if (pos.x > 1 or pos.x < df.global.world.map.x_count) and (pos.y > 1 or pos.y < df.global.world.map.y_count) then
        local designation = dfhack.maps.getTileFlags(pos)
        local tile_type = dfhack.maps.getTileType(pos)
        if tile_attrs[tile_type].shape == df.tiletype_shape.WALL and designation.dig ~= df.tile_dig_designation.UpDownStair then
            designation.dig=df.tile_dig_designation.UpDownStair
            set_priority( {pos=pos} , 3)
            dfhack.maps.getTileBlock(pos).flags.designated = true
        end
    end
end



local function writeFile (str, type, filename) 
    file = io.open("./hack/raw/"..(filename or "tmp"), type)  -- w+ a
    file:write(str)
    file:close()
end

local function p2p (pos1, pos2) 
    return math.sqrt((pos2.x - pos1.x)*(pos2.x - pos1.x) + (pos2.y - pos1.y)*(pos2.y - pos1.y))
end

local function dig_up_down_stair(pos1, pos2) 
    for i=pos1.x, pos2.x, (pos1.x > pos2.x and -1 or 1) do 
        for j=pos1.y, pos2.y, (pos1.y > pos2.y and -1 or 1) do 
            for z=pos1.z, pos2.z, (pos1.z > pos2.z and -1 or 1) do 
                designateStair({x=i, y=j, z=z})
            end
        end
    end
end

local function yu_gu_wa_func (pos) 
    for j=pos.y,1,-5 do
        for i=df.global.world.map.x_count-1,1,-1 do
            designateDig({x=i, y=j, z=df.global.window_z})
        end
    end
    for j=pos.y+5,df.global.world.map.y_count-1,5 do
        for i=df.global.world.map.x_count-1,1,-1 do
            designateDig({x=i, y=j, z=df.global.window_z})
        end
    end
    for i=df.global.world.map.y_count-1,1,-1 do
        designateDig({x=pos.x, y=i, z=df.global.window_z})
    end
end

local function round_dig_func (pos,r) 
    for i=pos.y-r,pos.y+r,1 do
        for j=pos.x-r,pos.x+r,1 do
            if p2p({x=j,y=i}, pos) <= (r+0.3) then 
                designateDig({x=j, y=i, z=df.global.window_z})
            end
        end
    end
end

local function bed_room_func (pos) 
    tmpn = {-10, 0 , 10}  
    for index,v in ipairs(tmpn) do 
        for i=pos.x-21,pos.x+21,1 do
            designateDig({x=i, y=pos.y + v, z=df.global.window_z})
        end
    end 
    
    tmpx = {-22, 0 , 22}
    for index,v in ipairs(tmpx) do 
        for i=pos.y-10,pos.y+10,1 do
            designateDig({x=pos.x+v, y=i, z=df.global.window_z})
        end
    end
    

    tmpn2 = {3, -3, 7, -7}  
    tmpn3 = {1, -1, 9, -9}
    for index,v in ipairs(tmpn2) do 
        for i=pos.x-3,pos.x-21,-4 do
            designateDig({x=i, y=pos.y+tmpn3[index], z=df.global.window_z})
            designateDig({x=i, y=pos.y+v, z=df.global.window_z})
            designateDig({x=i-1, y=pos.y+v, z=df.global.window_z})
            designateDig({x=i+1, y=pos.y+v, z=df.global.window_z})
            designateDig({x=i, y=pos.y+v-1, z=df.global.window_z})
            designateDig({x=i-1, y=pos.y+v-1, z=df.global.window_z})
            designateDig({x=i+1, y=pos.y+v-1, z=df.global.window_z})
            designateDig({x=i, y=pos.y+v+1, z=df.global.window_z})
            designateDig({x=i-1, y=pos.y+v+1, z=df.global.window_z})
            designateDig({x=i+1, y=pos.y+v+1, z=df.global.window_z})
        end
        for i=pos.x+3,pos.x+21,4 do
            designateDig({x=i, y=pos.y+tmpn3[index], z=df.global.window_z})
            designateDig({x=i, y=pos.y+v, z=df.global.window_z})
            designateDig({x=i-1, y=pos.y+v, z=df.global.window_z})
            designateDig({x=i+1, y=pos.y+v, z=df.global.window_z})
            designateDig({x=i, y=pos.y+v-1, z=df.global.window_z})
            designateDig({x=i-1, y=pos.y+v-1, z=df.global.window_z})
            designateDig({x=i+1, y=pos.y+v-1, z=df.global.window_z})
            designateDig({x=i, y=pos.y+v+1, z=df.global.window_z})
            designateDig({x=i-1, y=pos.y+v+1, z=df.global.window_z})
            designateDig({x=i+1, y=pos.y+v+1, z=df.global.window_z})
        end
    end
    


end


function count_this(to_be_counted)
    local count = -1
    local var1 = ""
    while var1 ~= nil do
        count = count + 1
        var1 = (to_be_counted[count])
    end
    count=count-1
    return count
end

local function keyInData(data, key) 
    local t = type(data)
    if t == "table" then
        if getmetatable(data) then
            for key2, _ in ipairs(data) do
                if key2 == key then
                    return true
                end
            end
        end
        return false
    elseif t == "userdata" then
        if getmetatable(data) then
            for key2, _ in pairs(data) do
                if key2 == key then
                    return true
                end
            end
        end
        return false
    else 
        return false
    end
end

local function turnJson(data, stack)
    if stack <= 0 then
        return tostring(data)
    end
    local t = type(data)
    if t == "string" or t == "number" or t == "boolean" then
        return data
    elseif t == "table" then
        local copyData = {}
        for key, v in ipairs(data) do
            if type(v) == "userdata" and not getmetatable(v) then
                copyData[key] = "not for iterator"
            else 
                copyData[key] = turnJson(v, stack-1)
            end
        end
        return copyData
    elseif t == "userdata" then
        local copyData = {}
        local utflags = utils.list_bitfield_flags(data)   
        for key, v in pairs(utflags) do
            if type(data[v]) == "userdata" and not getmetatable(data[v]) then
                copyData[v] = "not for iterator"
            else 
                copyData[v] = turnJson(data[v], stack-1)
            end
        end
        return copyData
    else
        return "type:"..t
    end
end


-- todo 自动熔炼物品 筛选 武器 盔甲 盾牌 弹药 可熔炼的 未被持有 未上锁 不是神器 未标记为熔炼的     材料为(铁铜)的
local function meltItem(mat, qa) 
    -- local rawsStrs = ""
    for id, item in ipairs(df.global.world.items.other.IN_PLAY) do
        local flags = item.flags
        if item and not flags.forbid and not flags.trader and not flags.melt and not dfhack.items.getHolderUnit(item) and not flags.dump then
            local ID = df.item_type[item:getType()]
            if ID and dfhack.items.getSubtypeCount(df.item_type[ID]) ~= -1 and item.mat_type then
                local des = dfhack.items.getDescription(item, 0, true)
                local matInfo = dfhack.matinfo.decode(item.mat_type,item.mat_index)
                local matName = matInfo:toString()
                local subTypeId = item.subtype.id
                local quality = item.quality   
                if flags.artifact_mood then 
                    quality = 6
                end
                -- subTypeId 匹配 武器 盔甲 弹药
                local subTypeName = string.match(subTypeId, '^ITEM_([^_]*)_')
                if matName == "copper" or matName == "iron" or matName == "bronze" or matName == "silver" or matName == "platinum" or matName == "steel" or matName == "adamantine" or matName == "bismuth bronze" or matName == "divine metal"  then
                    if subTypeName then
                        if subTypeName =="AMMO" or subTypeName =="SHIELD" or subTypeName =="WEAPON" or subTypeName =="ARMOR" or subTypeName =="HELM" or subTypeName =="GLOVES" or subTypeName =="PANTS" or subTypeName =="SHOES" then
                            -- 再根据ui填写的材料 品质量
                            -- 如果有owned 取消owned
                            -- 将该物品标记为熔炼
                            if mat[matName] and qa[tostring(quality)] then
                                if not dfhack.items.getOwner(item) then
                                    -- dfhack.items.setOwner(item)
                                    local meltCount = -1
                                    for i, _ in pairs(df.global.world.items.other.ANY_MELT_DESIGNATED) do
                                        meltCount = meltCount + 1
                                    end
                                    df.global.world.items.other.ANY_MELT_DESIGNATED:insert("#", item)
                                    item.flags.melt = true
                                end
                                -- table.insert(df.global.world.items.other.ANY_MELT_DESIGNATED, item)
                                -- rawsStrs = rawsStrs..tostring(id)..":("..tostring(subTypeId or "")..")<"..tostring(quality)..">"..des.." "..matName.."\n"
                            end
                        end
                    else 
                        -- todo 处理其他物品 非AMMO SHIELD WEAPON ARMOR HELM GLOVES PANTS SHOES
                    end
                end
                

                -- local utflags = utils.list_bitfield_flags(flags)
                -- rawsStrs = rawsStrs..table.concat(utflags, ' ').."\n"
                -- if des == "(llama wool trousers)" then
                -- local matInfo = dfhack.matinfo.decode(item.mat_type,item.mat_index)   -- matInfo:toString() silver
                
                -- writeFile(json.encode(turnJson(matInfo:toString(), 10)),"w+","silverWarHammerMat")
                -- 
            end
        end
    end
    -- writeFile(rawsStrs,"w+","tmp")
end

local function dump_rottens()   -- 筛选 未上锁的 未标记为垃圾的 腐烂的 标记为dump
    local raw_x_item = ""
    for id, item in ipairs(df.global.world.items.other.IN_PLAY) do
        if item then
            local flags = item.flags
            if flags.rotten and not flags.forbid and not flags.dump then 
                    if dfhack.items.getOwner(item) then
                        dfhack.items.setOwner(item)
                    end
                    local desName = dfhack.items.getDescription(item, 0, true)  -- name
                    raw_x_item = raw_x_item..id..":"..desName.." pos:"..item.pos.x.." "..item.pos.y.." "..item.pos.z.."\n"
                    -- flags.dump = true
            end
        end
    end
    writeFile(raw_x_item, "w+", "dumpItem")
end
-- dump_rottens()
local function cancel_own_x_item()   -- 将筛选出的物品取消掉owned  筛选 不被单位持有的 未上锁的 未标记为垃圾的 未标记为熔炼的 以及磨损或者腐烂的
    for id, item in ipairs(df.global.world.items.other.IN_PLAY) do
        if item then
            local flags = item.flags
            if not dfhack.items.getHolderUnit(item) and not flags.forbid and not flags.dump and not flags.melt and dfhack.items.getOwner(item) then 
                if item.wear > 0 or flags.rotten then
                    dfhack.items.setOwner(item)
                end
            end
        end
    end
end
local function export_dfs_info_func() 

    local raws = df.global.world.units.active
    local obj = {}

    for cid, unit in pairs(raws) do
        if dfhack.units.isOwnGroup(unit) and dfhack.units.isActive(unit) then 
            local desName = dfhack.units.getReadableName(unit)  -- name
            obj[tostring(cid)] = {}
            obj[tostring(cid)].desName = desName
            obj[tostring(cid)].stressLevel = dfhack.units.getStressCategory(unit)
            obj[tostring(cid)].stress = unit.status.current_soul.personality.stress
            obj[tostring(cid)].sane = dfhack.units.isSane(unit) -- zb werewolf
            obj[tostring(cid)].craze = dfhack.units.isCrazed(unit) -- craze
            obj[tostring(cid)].zuzou = dfhack.units.isHidingCurse(unit)  -- zu
            obj[tostring(cid)].vampire = dfhack.units.isBloodsucker(unit) -- 
            obj[tostring(cid)].age = string.format("%.2f", dfhack.units.getAge(unit))
            obj[tostring(cid)].trueage = string.format("%.2f", dfhack.units.getAge(unit, true))
            obj[tostring(cid)].jobSkill = ""
            obj[tostring(cid)].items = ""
            if unit.inventory then
                for _, inventory in pairs(unit.inventory) do
                    if inventory and inventory.item then
                        obj[tostring(cid)].items = obj[tostring(cid)].items..";"..dfhack.items.getDescription(inventory.item, 0, false)
                    end
                end
            end
            -- {
            --     "flags": {
            --         "remembered_reflected_on": true,
            --         "remembered_shortterm": true,
            --         "unk2": true
            --     },
            --     "severity": 0,
            --     "strength": 0,
            --     "subthought": -1,
            --     "thought": 55,
            --     "type": 167,
            --     "unk2": 0,
            --     "unk7": 0,
            --     "year": 107,
            --     "year_tick": 193226
            -- }
            -- thoughts
            local emoStr = ""
            local emotions=unit.status.current_soul.personality.emotions
            if emotions then
                for _, emo in pairs(emotions) do
                    local emolog = ""
                    emolog = emolog..emo.type..";"..emo.thought..";"..emo.year..";"..emo.year_tick..";"..emo.strength..";"..emo.severity..";"
                    for flagkey,flagV in pairs(emo.flags) do 
                        if flagV then
                            emolog = emolog..","..flagkey
                        end
                    end
                    emoStr = emoStr..emolog.."&"
                end
            end
            obj[tostring(cid)].emoStr = emoStr

            -- print("'"..df.job_skill.attrs[i].caption.."' "..df.job_skill[i].." Type: "..df.job_skill_class[df.job_skill.attrs[i].type])


            local count_max = count_this(df.job_skill)
            local i
            for i=0, count_max do
                local skillLevel = dfhack.units.getNominalSkill(unit,i)
                obj[tostring(cid)].jobSkill = obj[tostring(cid)].jobSkill..skillLevel.." "
            end

        end
    end

    writeFile(json.encode(obj) , 'w+', "unitsInfo.js")


    -- local citis = ''
    -- local citizens = dfhack.units.getCitizens()
    -- -- dfhack.units.getUnitsInBox(x1,y1,z1,x2,y2,z2[,filter]) 指定坐标内的单元
    -- for cid, unit in pairs(citizens) do
    --     local desName = dfhack.units.getReadableName(unit)  -- name
    --     local stress = dfhack.units.getStressCategory(unit)  -- 压力
    --     local sane = dfhack.units.isSane(unit) -- zb werewolf
    --     local craze = dfhack.units.isCrazed(unit) -- craze
    --     local zuzou = dfhack.units.isHidingCurse(unit)  -- zuzou
    --     local vampire = dfhack.units.isBloodsucker(unit) -- 
    --     local age = string.format("%.2f", dfhack.units.getAge(unit))
    --     local trueage = string.format("%.2f", dfhack.units.getAge(unit, true))




    --     citis = citis..desName.."&"..stress.."&"..age.."&"..trueage.."&"
    --     ..tostring(sane).."&"..tostring(craze).."&"..tostring(zuzou).."&"..tostring(vampire).."&"
        
    --     local count_max = count_this(df.job_skill)
    --     local i
    --     for i=0, count_max do
    --         -- writeFile("'"..df.job_skill.attrs[i].caption.."' "..df.job_skill[i].." Type: "..df.job_skill_class[df.job_skill.attrs[i].type].."\n", "a")
    --         local skillLevel = dfhack.units.getNominalSkill(unit,i)
    --         citis = citis..skillLevel.."&"
    --     end
        
    --     citis = citis.. "\n"
    -- end
    -- writeFile(citis, 'w+')
end
-- pause(0)
print('area:')
print('    The z-level is z='..df.global.window_z)
print('    The cursor is at x='..df.global.cursor.x..', y='..df.global.cursor.y)
print('    The window is '..df.global.gps.dimx..' tiles wide and '..df.global.gps.dimy..' tiles high')
if df.global.gps.mouse_x == -1 then print('    The mouse is not in the DF window') else
print('    The mouse is at x='..df.global.gps.mouse_x..', y='..df.global.gps.mouse_y..' within the window') end

print('    globalX'..df.global.world.map.x_count..'  globalY'..df.global.world.map.y_count)

-- local tmppos = {x=124,y=105,z=100}
-- dfhack.gui.pauseRecenter(tmppos)   
-- local designationt = dfhack.maps.getTileFlags(tmppos)
-- designationt.dig = df.tile_dig_designation.Default

-- df.emotion_type.attrs
local raws = df.global.world.items.other.ANY_MELT_DESIGNATED
-- local rawsStrs = json.encode(turnJson(raws,3))
-- local rawsStrs = ""

-- for cid, item in ipairs(raws) do
    -- if dfhack.units.isOwnGroup(item) and dfhack.units.isActive(item) then 
    --     local desName = dfhack.units.getReadableName(item)  -- name
    --     rawsStrs = rawsStrs..cid..":"..desName.." \n"
    -- end
    -- rawsStrs = rawsStrs..cid.." \n"

    -- if cid == 117 then 
        -- local desName = dfhack.units.getReadableName(item)  -- name
        -- rawsStrs = rawsStrs..cid..":"..desName.." \n"
        -- for cid, inventory in pairs(item.inventory) do
        --     -- rawsStrs = rawsStrs..toString(cid).."\n"
        --     if inventory and inventory.item then
        --         rawsStrs = rawsStrs..dfhack.items.getDescription(inventory.item, 0, true).."\n"
        --     end
        -- end





--         rawsStrs = rawsStrs.."stress:"..item.status.current_soul.personality.stress.." \n"
        -- rawsStrs = rawsStrs..json.encode(turnJson(item.inventory, 10))
        
        -- writeFile(json.encode(turnJson(item, 10)),"w+", "dw036.js")

        -- rawsStrs = rawsStrs..json.encode(turnJson(item, 10))
        -- local utflags = utils.list_bitfield_flags(item)   -- reports:log last_year last_year_tick    texpos 0 1 2     health 身体能力
        -- for key, v in pairs(utflags) do
        --     rawsStrs = rawsStrs..key..":"..v.."\n"
        -- end
        
        -- for key, v in pairs(item) do
        --     local t = type(v)
        --     if t == "number" then
        --         rawsStrs = rawsStrs..key..":"..v.."\n"
        --     elseif t == "string" then
        --         rawsStrs = rawsStrs..key..":"..v.."\n"
        --     elseif key == "inventory" then
        --         rawsStrs = rawsStrs..key..":\n"
        --         for key2, item2 in pairs(v) do 
        --             local item2des = dfhack.items.getDescription(item2.item, 0, true)
        --             rawsStrs = rawsStrs..item2des.."\n"
        --         end
        --     elseif key == "status" then
        --         rawsStrs = rawsStrs..key..":"..tostring(v.souls).."\n"
        --         -- misc_traits demand_timeout mandate_timeout attacker_ids attacker_cntdn face_direction 
        --         -- artifact_name souls current_soul demands labors wrestle_items observed_traps complaints 
        --         -- parleys requests coin_debts unk_1 unk_2 unk_3 unk_4 unk_5 adv_sleep_timer recent_job_area recent_jobs

        --         -- status2 limbs_stand_max limbs_stand_count limbs_grasp_max limbs_grasp_count limbs_fly_max limbs_fly_count 
        --         -- body_part_temperature add_path_flags liquid_type liquid_depth histeventcol_id
        --         rawsStrs = rawsStrs..table.concat(utils.list_bitfield_flags(v.souls), ' ').."\n"
        --         for key2, item2 in pairs(v.souls) do 
        --             rawsStrs = rawsStrs..table.concat(utils.list_bitfield_flags(item2), ' ').."\n"
        --             rawsStrs = rawsStrs..table.concat(utils.list_bitfield_flags(item2.personality), ' ').."\n"
        --             rawsStrs = rawsStrs..tostring(item2.personality.stress).."\n"
        --         end
        --     else 
        --         rawsStrs = rawsStrs..key.."\n"
        --     end
        -- end
    -- end
    -- if cid == 720 then
        -- if item.pos and item.pos.x and item.pos.x > -30000 then

            -- local des = dfhack.items.getDescription(item, 0, true)
            -- rawsStrs = rawsStrs.."name: "..des.."\n"
            -- for key, v in pairs(item) do
            --     local t = type(v)
            --     if t == "number" then
            --         rawsStrs = rawsStrs..key..":"..v.."\n"
            --     elseif t == "string" then
            --         rawsStrs = rawsStrs..key..":"..v.."\n"
            --     else 
            --         rawsStrs = rawsStrs..key.."\n"
            --     end
            -- end
            -- print(item.pos.x.." "..item.pos.y.." "..item.pos.z)
            -- dfhack.gui.pauseRecenter(item.pos)
        -- end
    -- end
-- end
-- 



 



-- 筛选库存的 神器quality=5 flags.artifact flags.artifact_mood  上锁的flags.forbid 损坏wear>0 腐坏flags.rotten  
-- 质量quality  熔炼flags.melt  subtype.id 子类型id 可熔炼
-- for id, item in ipairs(df.global.world.items.other.IN_PLAY) do
--     local flags = item.flags
--     if item and not flags.forbid and not flags.melt and not dfhack.items.getHolderUnit(item) and not flags.dump then
--         local ID = df.item_type[item:getType()]
--         if ID and dfhack.items.getSubtypeCount(df.item_type[ID]) ~= -1 then
--             local des = dfhack.items.getDescription(item, 0, true)
--             local matInfo = dfhack.matinfo.decode(item.mat_type,item.mat_index)
--             local matName = matInfo:toString()
--             local subTypeId = item.subtype.id
--             local quality = item.quality   
--             if flags.artifact_mood then 
--                 quality = 6
--             end
--             -- subTypeId 匹配 武器 盔甲 弹药
--             local subTypeName = string.match(subTypeId, '^ITEM_([^_]*)_')
--             if matName == "copper" or matName == "iron" or matName == "bronze" or matName == "silver" or matName == "platinum" or matName == "steel" or matName == "adamantine" or matName == "bismuth bronze" or matName == "divine metal"  then
--                 if subTypeName and subTypeName =="AMMO" or subTypeName =="WEAPON" or subTypeName =="ARMOR" or subTypeName =="HELM" or subTypeName =="GLOVES" or subTypeName =="PANTS" or subTypeName =="SHOES" then
--                     -- 再根据ui填写的材料 品质量
--                     -- 如果有owned 取消owned
--                     -- 将该物品标记为熔炼
                    
--                     rawsStrs = rawsStrs..tostring(id)..":("..tostring(subTypeId or "")..")<"..tostring(quality)..">"..des.." "..matName.."\n"
--                 end
--             end

--             -- local utflags = utils.list_bitfield_flags(flags)
--             -- rawsStrs = rawsStrs..table.concat(utflags, ' ').."\n"
--             -- if des == "(llama wool trousers)" then
--             -- local matInfo = dfhack.matinfo.decode(item.mat_type,item.mat_index)   -- matInfo:toString() silver
            
--             -- writeFile(json.encode(turnJson(matInfo:toString(), 10)),"w+","silverWarHammerMat")
--             -- 
--         end
--     end
-- end

-- writeFile( rawsStrs,"w+")

-- local list_of_plants_string=""
-- local plants=df.global.world.raws.plants.all
-- for k=0,#plants-1 do
--     name=plants[k].id
--     list_of_plants_string=list_of_plants_string..name.."\n"
-- end
-- writeFile( "\n PLANTS:"..list_of_plants_string,"w+")

-- local count_max = count_this(df.job_skill)
-- local i
-- for i=0, count_max do
--     writeFile("'"..df.job_skill.attrs[i].caption.."' "..df.job_skill[i].." Type: "..df.job_skill_class[df.job_skill.attrs[i].type].."\n", "a")
-- end




-- for k,id in ipairs(entity.resources.weapon_type) do
--     local def = defs.weapons[id]
--     local name = def.name
--     if def.skill_ranged >= 0 then
--         local slevel = dfhack.units.getNominalSkill(citizens[1],def.skill_ranged)
--         writeFile(def.skill_ranged..":"..name..":"..slevel.."\n", "a")
--     else
--         local slevel = dfhack.units.getNominalSkill(citizens[1],def.skill_melee)
--         writeFile(def.skill_melee..":"..name..":"..slevel.."\n", "a")
--     end
-- end

Smelt = defclass(Smelt, widgets.Window)
Smelt.ATTRS {
    frame_title='select mat and quality to melt',
    frame={r=0, t=1, w=25, h=35},
}

function Smelt:init()
    self.mat = s_mat
    self.quality = s_quality
    self:addviews{
        widgets.HotkeyLabel{
            frame={t=0, l=0},
            view_id='copper',
            label='copper',
            text_pen = self.mat.copper and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.mat.copper = not self.mat.copper 
                -- automelt.set_s_mat(self.mat)
                self.subviews.copper.text_pen = self.mat.copper and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=1, l=0},
            view_id='iron',
            label='iron',
            text_pen = self.mat.iron and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat.iron = not self.mat.iron 
                -- automelt.set_s_mat(self.mat)
                self.subviews.iron.text_pen = self.mat.iron and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=2, l=0},
            view_id='bronze',
            label='bronze',
            text_pen = self.mat.bronze and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat.bronze = not self.mat.bronze 
                -- automelt.set_s_mat(self.mat)
                self.subviews.bronze.text_pen = self.mat.bronze and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=3, l=0},
            view_id='bismuth bronze',
            label='bismuth bronze',
            text_pen = self.mat["bismuth bronze"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat["bismuth bronze"] = not self.mat["bismuth bronze"] 
                -- automelt.set_s_mat(self.mat)
                self.subviews['bismuth bronze'].text_pen = self.mat['bismuth bronze'] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=4, l=0},
            view_id='steel',
            label='steel',
            text_pen = self.mat.steel and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat.steel = not self.mat.steel 
                -- automelt.set_s_mat(self.mat)
                self.subviews['steel'].text_pen = self.mat['steel'] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=5, l=0},
            view_id='silver',
            label='silver',
            text_pen = self.mat.silver and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat.silver = not self.mat.silver 
                -- automelt.set_s_mat(self.mat)
                self.subviews.silver.text_pen = self.mat.silver and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=6, l=0},
            view_id='platinum',
            label='platinum',
            text_pen = self.mat.platinum and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat.platinum = not self.mat.platinum 
                -- automelt.set_s_mat(self.mat)
                self.subviews.platinum.text_pen = self.mat.platinum and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=7, l=0},
            view_id="divine metal",
            label="divine metal",
            text_pen = self.mat["divine metal"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat["divine metal"] = not self.mat["divine metal"] 
                -- automelt.set_s_mat(self.mat)
                self.subviews["divine metal"].text_pen = self.mat["divine metal"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=8, l=0},
            view_id='adamantine',
            label='adamantine',
            text_pen = self.mat.adamantine and COLOR_YELLOW or COLOR_GREY,
            on_activate=function()  
                self.mat.adamantine = not self.mat.adamantine 
                -- automelt.set_s_mat(self.mat)
                self.subviews.adamantine.text_pen = self.mat.adamantine and COLOR_YELLOW or COLOR_GREY
            end,
        },

        widgets.HotkeyLabel{
            frame={t=9, r=0},
            view_id='quailty0',
            label='quailty0',
            text_pen = self.quality["0"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.quality["0"] = not self.quality["0"] 
                -- automelt.set_s_quality(self.quality)
                self.subviews.quailty0.text_pen = self.quality["0"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=10, r=0},
            view_id='quailty1',
            label='quailty1',
            text_pen = self.quality["1"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.quality["1"] = not self.quality["1"] 
                -- automelt.set_s_quality(self.quality)
                self.subviews.quailty1.text_pen = self.quality["1"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=11, r=0},
            view_id='quailty2',
            label='quailty2',
            text_pen = self.quality["2"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.quality["2"] = not self.quality["2"] 
                -- automelt.set_s_quality(self.quality)
                self.subviews.quailty2.text_pen = self.quality["2"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=12, r=0},
            view_id='quailty3',
            label='quailty3',
            text_pen = self.quality["3"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.quality["3"] = not self.quality["3"] 
                -- automelt.set_s_quality(self.quality)
                self.subviews.quailty3.text_pen = self.quality["3"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=13, r=0},
            view_id='quailty4',
            label='quailty4',
            text_pen = self.quality["4"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.quality["4"] = not self.quality["4"] 
                -- automelt.set_s_quality(self.quality)
                self.subviews.quailty4.text_pen = self.quality["4"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=14, r=0},
            view_id='quailty5',
            label='quailty5',
            text_pen = self.quality["5"] and COLOR_YELLOW or COLOR_GREY,
            on_activate=function() 
                self.quality["5"] = not self.quality["5"] 
                -- automelt.set_s_quality(self.quality)
                self.subviews.quailty5.text_pen = self.quality["5"] and COLOR_YELLOW or COLOR_GREY
            end,
        },
        widgets.HotkeyLabel{
            frame={t=15, l=2},
            label='ok',
            on_activate=function()  
                -- writeFile(json.encode(self.mat),"w+","tmp")
                -- writeFile(json.encode(self.quality),"a","tmp")
                meltItem(self.mat, self.quality)
                self:hide()
            end,
        },
    }
end
-- function Smelt:onRenderBody(painter)
--     for key,sep in ipairs(painter) do
--         writeFile(key+"\n","a+", "tmp")  
--     end
-- end
function Smelt:show()
    self.visible = true
    self:setFocus(true)
    self:updateLayout()
end

function Smelt:hide()
    self:setFocus(false)
    self.visible = false
end

function Smelt:onInput(keys)
    if keys.LEAVESCREEN or keys._MOUSE_R_DOWN then
        self:hide()
        return true
    end
    Smelt.super.onInput(self, keys)
    return true
end

Shenxian = defclass(Shenxian, widgets.Window)
Shenxian.ATTRS {
    frame_title='Shenxian',
    frame={w=48, h=24, r=2, t=18},
    resizable=true,
    resize_min={h=10},
    autoarrange_subviews=true,
}

function Shenxian:init()
    self.mark = nil
    self:reset_double_click() 

    self:addviews{
        widgets.HotkeyLabel{
            frame={l=0},
            label='yu gu wa',
            key='CUSTOM_CTRL_D',
            auto_width=true,
            on_activate=self:callback('yu_gu_wa'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='change units name',
            key='CUSTOM_CTRL_N',
            auto_width=true,
            on_activate=self:callback('change_name'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='bedroom_dig',
            key='CUSTOM_CTRL_B',
            auto_width=true,
            on_activate=self:callback('bedroom_dig'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.EditField{
            view_id="round_r",
            frame={l=2},
            label_text="round_r: ",
            text = "10",
            on_char=function(ch) return ch:match("%d") end,
            on_submit=function(text)
                self.round_r = tonumber(text)
            end
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='round_pad_dig',
            key='CUSTOM_CTRL_P',
            auto_width=true,
            on_activate=self:callback('round_pad_dig'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='up down stair',
            key='CUSTOM_CTRL_L',
            auto_width=true,
            on_activate=self:callback('dig_up_down_stair'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='output dfs info',
            key='CUSTOM_CTRL_U',
            auto_width=true,
            on_activate=self:callback('export_dfs_info'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='cancel owned X or rooten item',
            key='CUSTOM_CTRL_G',
            auto_width=true,
            on_activate=self:callback('cancelOwnXitem'),
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='check build',
            key='CUSTOM_CTRL_J',
            auto_width=true,
            on_activate=function()
                dfhack.job.checkBuildingsNow()
            end,
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='check designations',
            key='CUSTOM_CTRL_W',
            auto_width=true,
            on_activate=function()
                dfhack.job.checkDesignationsNow()
            end,
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        widgets.HotkeyLabel{
            frame={l=0},
            label='melt item',
            key='CUSTOM_CTRL_M',
            auto_width=true,
            on_activate=function()
                -- 展示 材料和品质ui
                self.subviews.Smelt:show()
            end,
            -- enabled=function() return dfhack.gui.getMousePos() end,
        },
        -- widgets.ToggleHotkeyLabel{
        --     view_id="enable_toggle",
        --     frame={t=0, l=0, w=31},
        --     label="Auto Melt Object",
        --     key="CUSTOM_CTRL_E",
        --     options={{value=true, label="Enabled", pen=COLOR_GREEN},
        --              {value=false, label="Disabled", pen=COLOR_RED}},
        --     on_change=function(val) dfhack.run_command{val and "enable" or "disable", "automelt"} end
        -- },
        Smelt{
            view_id='Smelt',
            visible=false,
        },
    }
    self:refresh_data()
end
function Shenxian:refresh_data()
    -- self.subviews.enable_toggle:setOption(automelt.isEnabled())
end
function Shenxian:reset_double_click()
    self.last_map_click_ms = 0
    self.last_map_click_pos = {}
    self.double_pre_pos = false
end


local to_pen = dfhack.pen.parse
local CURSOR_PEN = to_pen{ch='o', fg=COLOR_BLUE,
                         tile=dfhack.screen.findGraphicsTile('CURSORS', 5, 22)}
local BOX_PEN = to_pen{ch='X', fg=COLOR_GREEN,
                       tile=dfhack.screen.findGraphicsTile('CURSORS', 0, 0)}
local SELECTED_PEN = to_pen{ch='I', fg=COLOR_GREEN,
                       tile=dfhack.screen.findGraphicsTile('CURSORS', 1, 2)}



function Shenxian:yu_gu_wa()
    self.active = "yes"
    self.workType = "yu gu wa"
    if next(self.subviews) then
        self:updateLayout()
    end
end
function Shenxian:change_name()
    local citizens = dfhack.units.getCitizens()
    local maxIndex = 0
    for cid, unit in pairs(citizens) do
        local desName = dfhack.units.getReadableName(unit)  -- name
        local num = string.match(desName, '^`(%d+)[^%d]')
        if num then
            num = tonumber(num)
            if maxIndex < num then maxIndex = num end
        end
    end
    for cid, unit in pairs(citizens) do
        local desName = dfhack.units.getReadableName(unit)  -- name
        local num = string.match(desName, '^`(%d+)[^%d]')
        if not num then
            maxIndex = maxIndex + 1
            local nick = tostring(maxIndex)
            if #nick == 1 then 
                nick = "00"..nick 
            elseif #nick == 2 then
                nick = "0"..nick 
            end
            dfhack.units.setNickname(unit,nick)
        end
    end
    if next(self.subviews) then
        self:updateLayout()
    end
end

function Shenxian:bedroom_dig()
    self.active = "yes"
    self.workType = "bed room"
    if next(self.subviews) then
        self:updateLayout()
    end
end
function Shenxian:round_pad_dig()
    self.active = "yes"
    self.workType = "round dig"
    if next(self.subviews) then
        self:updateLayout()
    end
end
function Shenxian:dig_up_down_stair()
    self.active = "yes"
    self.workType = "up down stair"
    if next(self.subviews) then
        self:updateLayout()
    end
end

function Shenxian:export_dfs_info()
    export_dfs_info_func()
    if next(self.subviews) then
        self:updateLayout()
    end
end

function Shenxian:cancelOwnXitem()
    cancel_own_x_item()
    if next(self.subviews) then
        self:updateLayout()
    end
end

function Shenxian:onRenderFrame(dc, rect)
    Shenxian.super.onRenderFrame(self, dc, rect)
    if not dfhack.screen.inGraphicsMode() and not gui.blink_visible(500) then
        return
    end
    if not self.mark or not self.double_pre_pos then return end
    if self.workType ~= "up down stair" then return end
    -- local highlight_coords = self.selected_coords[df.global.window_z]
    -- if highlight_coords then
    --     local function get_overlay_pen(pos)
    --         if safe_index(highlight_coords, pos.y, pos.x) then
    --             return SELECTED_PEN
    --         end
    --     end
    --     guidm.renderMapOverlay(get_overlay_pen, self.selected_bounds[df.global.window_z])
    -- end

    -- -- draw selection box and cursor (blinking when in ascii mode)
    local cursor = dfhack.gui.getMousePos()
    local selection_bounds = self:get_bounds(cursor)
    if (selection_bounds) then
        -- writeFile(selection_bounds.x1.." "..selection_bounds.y1.." "..selection_bounds.z1.." "..selection_bounds.x2.." "..selection_bounds.y2.." "..selection_bounds.z2.." \n", "a")
        guidm.renderMapOverlay( function() return BOX_PEN end , selection_bounds)
    end
end
function Shenxian:onInput(keys)
    if Shenxian.super.onInput(self, keys) then return true end

    -- if keys._MOUSE_R_DOWN and self.mark then
    --     self.mark = nil
    --     self:updateLayout()
    -- --     self:dismiss()
    --     writeFile("input right")
    --     return true
    -- elseif 
    if keys._MOUSE_L_DOWN then
        if self:getMouseFramePos() then return true end
        local pos = dfhack.gui.getMousePos()
        if not pos then
            self:reset_double_click()
            return false
        end


        local now_ms = dfhack.getTickCount()

        if same_xyz(pos, self.last_map_click_pos) and
                now_ms - self.last_map_click_ms <= 500 then
            
            if self.active == "yes" then 
                if self.workType == "up down stair" then
                    -- dfhack.gui.pauseRecenter(pos)
                    dig_up_down_stair(self.double_pre_pos, pos)
                end
            end

            self:reset_double_click()
            self.mark = nil
            self:updateLayout()

            return true
        end
        
        self.mark = pos
        self.last_map_click_ms = now_ms
        self.last_map_click_pos = pos
        if not self.double_pre_pos then
            self.double_pre_pos = pos 
        end

        if self.active == "yes" then
            if self.workType == "yu gu wa" then 
                -- dfhack.gui.pauseRecenter(self.mark)
                yu_gu_wa_func(self.mark)
            elseif self.workType == "bed room" then
                -- dfhack.gui.pauseRecenter(self.mark)
                bed_room_func(self.mark)
            elseif self.workType == "round dig" then
                round_dig_func(self.mark, self.round_r or 10)
            end
        end
        
        -- if self.mark then
        --     self:select_box(self:get_bounds(pos))
        --     self:reset_double_click()
        --     writeFile("清除 mark:"..self.mark.x.." "..self.mark.y.." "..self.mark.z.."\n", "a")
        --     self.mark = nil
        --     self:updateLayout()
        --     return true
        -- end
        -- self.mark = pos



        
        
        self:updateLayout()
        return true
    end
    
end

function Shenxian:get_bounds(curson)
    local cur = dfhack.gui.getMousePos()
    return {
        x1=math.min( self.double_pre_pos.x, cur.x),
        x2=math.max(self.double_pre_pos.x, cur.x),
        y1=math.min( self.double_pre_pos.y,cur.y ),
        y2=math.max( self.double_pre_pos.y,cur.y),
        z1=math.min(self.double_pre_pos.z,cur.z),
        z2=math.max(self.double_pre_pos.z,cur.z),
    }
end

-- ShenXianScreen
ShenxianScreen = defclass(ShenxianScreen, gui.ZScreen)
ShenxianScreen.ATTRS {
    focus_path='shenxian',
    pass_movement_keys=true,
    pass_mouse_clicks=false,
}

function ShenxianScreen:init()
    self:addviews{Shenxian{}}
end

function ShenxianScreen:onDismiss()
    view = nil
end

if not dfhack.isMapLoaded() then
    qerror('seedwatch requires a map to be loaded')
end

view = view and view:raise() or ShenxianScreen{}:show()
